#include <iostream>

using namespace std;
//类模板与友元
//类模板配合友元函数的类内和类外实现
//全局函数类内实现 - 直接在类内声明友元即可
//全局函数类外实现 - 需要提前让编译器知道全局函数的存在

//全局函数配合友元  类外实现 - 先做函数模板声明，下方在做函数模板定义，在做友元
template<typename T, typename C>
class Person;

//如果声明了函数模板，可以将实现写到后面，否则需要将实现体写到类的前面让编译器提前看到
template<class T, class C>
void printPerson2(Person<T, C> &p);

template<typename T, typename C>
class Person {
    //全局函数配合友元   类内实现
    friend void printPerson(Person<T, C> &p) {
        cout << "name:" << p.name << ",age:" << p.age << endl;
    }

    //全局函数配合友元  类外实现
    friend void printPerson2<>(Person<T, C> &p);

private:
    T name;
    C age;
public:
    Person(T name, C age) {
        this->name = name;
        this->age = age;
    }
};

template<typename T, typename C>
void printPerson2(Person<T, C> &p) {
    cout << "name:" << p.name << ",age:" << p.age << endl;
}

void test1() {
    Person<string, int> p("tom", 18);
    printPerson(p);
}

void test2() {
    Person<string, int> p("jerry", 19);
    printPerson2(p);
}

int main() {
    test1();
    test2();
    return 0;
}